const express = require('express');
const router = express.Router();
const {Op} = require('sequelize');
const Goods = require('../models/goods');
const Type = require('../models/type');
const Tag = require('../models/tag');
const History = require('../models/history');
const RelatedFigures = require('../models/related_figures');
const RelatedEvents = require('../models/related_events');
const RecommendService = require('../services/recommendService');
const UserAction = require('../models/user_action')

//根据商品id查询收藏数，点赞数
router.get('/liekAndViewCount', async (req, res)=> {
    try{
        const {goods_id} = req.query;
        
        const liekCount = await UserAction.count({
            where: {
                goods_id: goods_id,
                action_type: 'collect'
            }
        })
        const viewCount = await UserAction.count({
            where: {
                goods_id: goods_id,
                action_type: 'view'
            }
        })
        res.send({
            code: 200,
            data: {
                like: liekCount,
                view: viewCount
            }
        })
        
    }catch(e){
        res.send({code: 500, message: e.message})
    }


})


/**
 * 分页查询工艺品列表
 */
router.get('/list', async (req, res) => {
    try {
        const {page = 1, pageSize = 10, name = '', type = null, region = '', period = ''} = req.query;
        const offset = (page - 1) * pageSize;
        const whereCondition = {}
        if (name && name.trim()) {
            whereCondition.name = {[Op.like]: `%${name.trim()}%`}
        }
        if (type && !isNaN(type)) {
            whereCondition.type = parseInt(type)
        }

        // 连接neo4j和mysql两个数据库进行混合查询
        let filteredIds = null;
        
        // 如果有地区或时期过滤条件，先通过Neo4j过滤
        if (region || period) {
            const session = req.neo4j.session();
            try {
                let query = `
                    MATCH (g:Goods)
                `;
                
                // 根据地区过滤
                if (region) {
                    query += `
                        MATCH (g)-[:BELONGS_TO_REGION]->(r:Region)
                        WHERE r.name CONTAINS $region
                    `;
                }
                
                // 根据时期过滤
                if (period) {
                    query += `
                        MATCH (g)-[:BELONGS_TO_PERIOD]->(p:Period)
                        WHERE p.name CONTAINS $period
                    `;
                }
                
                query += `
                    RETURN g.id as goodsId
                `;
                
                const result = await session.run(query, { region, period });
                filteredIds = result.records.map(record => record.get('goodsId'));
                
                // 如果没有符合条件的商品，直接返回空结果
                if (filteredIds.length === 0) {
                    return res.send({
                        code: 200,
                        list: [],
                        total: 0,
                        message: 'success'
                    });
                }
                
                // 将过滤后的ID添加到MySQL查询条件
                whereCondition.id = {[Op.in]: filteredIds};
            } finally {
                await session.close();
            }
        }

        const {count, rows} = await Goods.findAndCountAll({
            where: whereCondition,
            include: [
                // 类型表联查
                {model: Type, as: 'category', attributes: ['id', 'name']},
                // tags关联查询
                { model: Tag, as: 'tags', through: {attributes: []}, /**不返回中间表字段*/ attributes: ['id', 'name']},
                // 历史数据关联查询
                { model: History, as: 'history' },
                // 历史人物关联查询
                { model: RelatedFigures, as: 'historicalFigures' },
                // 历史事件关联查询
                { model: RelatedEvents, as: 'historicalEvents' }
            ],
            //分页参数
            offset: parseInt(offset),
            limit: parseInt(pageSize),
            //排序
            order: [['id', 'ASC']]
        });

        // 查询知识图谱数据
        const session = req.neo4j.session();
        try {
            // 获取所有商品ID
            const goodsIds = rows.map(item => item.id);
            
            // 批量查询知识图谱数据
            const query = `
                MATCH (g:Goods)
                WHERE g.id IN $goodsIds
                OPTIONAL MATCH (g)-[:BELONGS_TO_SCHOOL]->(s:CraftSchool)
                OPTIONAL MATCH (g)-[:CULTURAL_RELATION]->(c:Culture)
                OPTIONAL MATCH (g)-[:BELONGS_TO_REGION]->(r:Region)
                OPTIONAL MATCH (g)-[:BELONGS_TO_PERIOD]->(p:Period)
                OPTIONAL MATCH (g)-[:RELATED_TO_FIGURE]->(f:HistoricalFigure)
                OPTIONAL MATCH (g)-[:RELATED_TO_EVENT]->(e:HistoricalEvent)
                RETURN g.id as goodsId,
                       collect(distinct s) as craftSchools,
                       collect(distinct c) as culturalRelations,
                       collect(distinct r) as regions,
                       collect(distinct p) as periods,
                       collect(distinct f) as historicalFigures,
                       collect(distinct e) as historicalEvents
            `;
            
            const result = await session.run(query, { goodsIds });
            
            // 将知识图谱数据与商品数据关联
            const knowledgeGraphMap = {};
            result.records.forEach(record => {
                const goodsId = record.get('goodsId');
                knowledgeGraphMap[goodsId] = {
                    craftSchools: record.get('craftSchools').map(school => school?.properties || null).filter(Boolean),
                    culturalRelations: record.get('culturalRelations').map(culture => culture?.properties || null).filter(Boolean),
                    regions: record.get('regions').map(region => region?.properties || null).filter(Boolean),
                    periods: record.get('periods').map(period => period?.properties || null).filter(Boolean),
                    historicalFigures: record.get('historicalFigures').map(figure => figure?.properties || null).filter(Boolean),
                    historicalEvents: record.get('historicalEvents').map(event => event?.properties || null).filter(Boolean)
                };
            });
            
            // 将知识图谱数据添加到商品数据中
            const enrichedRows = rows.map(item => {
                const itemJson = item.toJSON();
                // 合并MySQL和Neo4j的历史人物数据
                const mysqlFigures = itemJson.historicalFigures || [];
                const neo4jFigures = (knowledgeGraphMap[item.id]?.historicalFigures || []);
                
                // 合并MySQL和Neo4j的历史事件数据
                const mysqlEvents = itemJson.historicalEvents || [];
                const neo4jEvents = (knowledgeGraphMap[item.id]?.historicalEvents || []);
                
                // 创建合并后的知识图谱对象
                const mergedKnowledgeGraph = {
                    ...knowledgeGraphMap[item.id] || {},
                    // 优先使用MySQL数据，Neo4j数据作为补充
                    historicalFigures: mysqlFigures.length > 0 ? mysqlFigures : neo4jFigures,
                    historicalEvents: mysqlEvents.length > 0 ? mysqlEvents : neo4jEvents
                };
                
                return {
                    ...itemJson,
                    knowledgeGraph: mergedKnowledgeGraph
                };
            });
            
            res.send({
                code: 200,
                list: enrichedRows,
                total: count,
                message: 'success'
            });
        } finally {
            await session.close();
        }
    } catch (e) {
        res.send({
            code: 500,
            message: e.message
        });
    }
});

// 查询详情
router.get('/:id', async (req, res) => {
    try {
        const {id} = req.params;
        const userId = req.user.userId; // 从认证中间件获取用户ID
        const goods = await Goods.findByPk(id, {
            include: [
                {
                    model: Type,
                    as: 'category',
                    attributes: ['id', 'name']
                },
                {
                    model: Tag,
                    as: 'tags',
                    through: {attributes: []},
                    attributes: ['id', 'name']
                },
                {
                    model: History,
                    as: 'history',
                    attributes: ['id', 'period', 'region', 'cultural_background', 'craft_process', 'cultural_value']
                },
                {
                    model: RelatedFigures,
                    as: 'historicalFigures'
                },
                {
                    model: RelatedEvents,
                    as: 'historicalEvents'
                }
            ]
        });

        if (!goods) {
            return res.send({
                code: 500,
                message: `未找到id为${id}的数据`
            });
        }

        // 记录用户浏览行为并获取知识图谱数据
        const recommendService = new RecommendService(req.neo4j, req.db);
        await recommendService.recordUserAction(userId, id, 'view');

        // 查询知识图谱数据
        const session = req.neo4j.session();
        try {
            const query = `
                MATCH (g:Goods {id: $goodsId})
                OPTIONAL MATCH (g)-[:HAS_HISTORY]->(h:History)
                OPTIONAL MATCH (g)-[:BELONGS_TO_SCHOOL]->(s:CraftSchool)
                OPTIONAL MATCH (g)-[:CULTURAL_RELATION]->(c:Culture)
                OPTIONAL MATCH (g)-[:BELONGS_TO_REGION]->(r:Region)
                OPTIONAL MATCH (g)-[:BELONGS_TO_PERIOD]->(p:Period)
                OPTIONAL MATCH (g)-[:RELATED_TO]->(rg:Goods)
                OPTIONAL MATCH (g)-[:RELATED_TO_FIGURE]->(f:HistoricalFigure)
                OPTIONAL MATCH (g)-[:RELATED_TO_EVENT]->(e:HistoricalEvent)
                RETURN h as history,
                       collect(distinct s) as craftSchools,
                       collect(distinct c) as culturalRelations,
                       collect(distinct r) as regions,
                       collect(distinct p) as periods,
                       collect(distinct rg {.*, type: labels(rg)[0]}) as relatedGoods,
                       collect(distinct f) as historicalFigures,
                       collect(distinct e) as historicalEvents
            `;
            const result = await session.run(query, { goodsId: id });
            const graphData = result.records[0];

            const knowledgeGraph = {
                history: graphData?.get('history')?.properties || null,
                craftSchools: graphData?.get('craftSchools')?.map(school => school?.properties) || [],
                culturalRelations: graphData?.get('culturalRelations')?.map(culture => culture?.properties) || [],
                regions: graphData?.get('regions')?.map(region => region?.properties) || [],
                periods: graphData?.get('periods')?.map(period => period?.properties) || [],
                relatedGoods: graphData?.get('relatedGoods')?.map(goods => goods) || [],
                historicalFigures: graphData?.get('historicalFigures')?.map(figure => figure?.properties) || [],
                historicalEvents: graphData?.get('historicalEvents')?.map(event => event?.properties) || []
            };
            
            // 在发送响应前处理和合并MySQL和Neo4j的数据
            const goodsJson = goods.toJSON();
            
            // 合并MySQL和Neo4j的历史人物数据
            const mysqlFigures = goodsJson.historicalFigures || [];
            const neo4jFigures = knowledgeGraph.historicalFigures || [];
            
            // 合并MySQL和Neo4j的历史事件数据
            const mysqlEvents = goodsJson.historicalEvents || [];
            const neo4jEvents = knowledgeGraph.historicalEvents || [];
            
            // 创建合并后的知识图谱对象，优先使用MySQL数据
            knowledgeGraph.historicalFigures = mysqlFigures.length > 0 ? mysqlFigures : neo4jFigures;
            knowledgeGraph.historicalEvents = mysqlEvents.length > 0 ? mysqlEvents : neo4jEvents;

            res.send({
                code: 200,
                data: {
                    ...goodsJson,
                    knowledgeGraph
                },
                message: 'success'
            });
        } finally {
            await session.close();
        }
    } catch (e) {
        res.send({
            code: 500,
            message: e.message
        });
    }
});

// 收藏
router.post('/favorite/:id', async (req, res) => {
    try {
        const goodsId = req.params.id;
        const userId = req.user.userId;

        // 记录收藏行为
        const recommendService = new RecommendService(req.db);
        await recommendService.recordUserAction(userId, goodsId, 'collect');

        res.send({
            code: 200,
            message: '收藏成功'
        });
    } catch (e) {
        res.send({
            code: 500,
            message: e.message
        });
    }
});
//修改或添加goods
router.post('/post', async (req, res) => {
    const session = req.neo4j.session();
    try {
        const {id, name, type, cover, tags = [], content, cultural_background, region, period, craft_process, cultural_value, related_figures = [], related_events = []} = req.body;

        // 创建或更新历史记录
        let historyId = null;
        if (period && region) {
            // 创建或查找历史记录
            const History = require('../models/history');
            let history;
            
            if (id) {
                // 如果是更新，先查找是否已有历史记录
                const goods = await Goods.findByPk(id);
                if (goods && goods.history_id) {
                    history = await History.findByPk(goods.history_id);
                    if (history) {
                        await history.update({
                            period,
                            region,
                            cultural_background: cultural_background || '',
                            craft_process: craft_process || '',
                            cultural_value: cultural_value || ''
                        });
                    }
                }
            }
            
            // 如果没有找到历史记录，则创建新的
            if (!history) {
                history = await History.create({
                    period,
                    region,
                    cultural_background: cultural_background || '',
                    craft_process: craft_process || '',
                    cultural_value: cultural_value || ''
                });
            }
            
            historyId = history.id;
        }

        let goods;
        if (id) {
            // 更新
            goods = await Goods.findByPk(id);
            if (!goods) {
                return res.send({code: 404, message: '商品不存在'});
            }

            await goods.update({
                name,
                type,
                cover,
                content,
                history_id: historyId
            });

            // 先删除原有标签关联
            await goods.setTags([]);

            // 更新Neo4j中的节点
            await session.run(`
                MATCH (g:Goods {id: $id})
                SET g.name = $name, g.type = $type,
                    g.cover = $cover, g.content = $content
            `, { id: goods.id, name, type, cover, content });
            
            // 删除原有的关系
            await session.run(`
                MATCH (g:Goods {id: $id})
                OPTIONAL MATCH (g)-[r:HAS_HISTORY|BELONGS_TO_SCHOOL|CULTURAL_RELATION]-()
                DELETE r
            `, { id: goods.id });
            
        } else {
            // 创建
            goods = await Goods.create({
                name,
                type,
                cover,
                content,
                history_id: historyId
            });

            // 在Neo4j中创建商品节点
            await session.run(`
                CREATE (g:Goods {
                    id: $id, name: $name, type: $type,
                    cover: $cover, content: $content
                })
            `, { id: goods.id, name, type, cover, content });
        }

        // 添加新的标签关联
        if (tags.length > 0) {
            await goods.addTags(tags);
            // 在Neo4j中创建标签关系
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                UNWIND $tagIds as tagId
                MATCH (t:Tag {id: tagId})
                MERGE (g)-[:HAS_TAG]->(t)
            `, { goodsId: goods.id, tagIds: tags });
        }

        // 如果有历史信息，创建历史节点和关系
        if (period && region) {
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                MERGE (h:History {id: $historyId, period: $period, region: $region, cultural_background: $cultural_background})
                MERGE (g)-[:HAS_HISTORY]->(h)
            `, { 
                goodsId: goods.id, 
                historyId: historyId,
                period, 
                region, 
                cultural_background: cultural_background || '' 
            });
            
            // 创建地区节点和关系
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                MERGE (r:Region {name: $region})
                MERGE (g)-[:BELONGS_TO_REGION]->(r)
            `, { goodsId: goods.id, region });
            
            // 创建朝代节点和关系
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                MERGE (p:Period {name: $period})
                MERGE (g)-[:BELONGS_TO_PERIOD]->(p)
            `, { goodsId: goods.id, period });
        }

        // 创建与工艺流派的关系
        if (craft_process) {
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                MERGE (s:CraftSchool {name: $craftProcess})
                MERGE (g)-[:BELONGS_TO_SCHOOL]->(s)
            `, { goodsId: goods.id, craftProcess: craft_process });
        }
        
        // 创建文化价值节点和关系
        if (cultural_value) {
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                MERGE (c:Culture {value: $culturalValue})
                MERGE (g)-[:CULTURAL_RELATION]->(c)
            `, { goodsId: goods.id, culturalValue: cultural_value });
        }

        // 更新与历史人物的关系 - 同时更新MySQL和Neo4j
        if (related_figures && related_figures.length > 0) {
            // 先删除MySQL中的旧数据
            await RelatedFigures.destroy({
                where: { goods_id: goods.id }
            });
            
            // 添加新数据到MySQL
            for (const figure of related_figures) {
                await RelatedFigures.create({
                    goods_id: goods.id,
                    name: figure.name,
                    description: figure.description || ''
                });
            }
            
            // 在Neo4j中创建关系
            // 先删除旧关系
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                OPTIONAL MATCH (g)-[r:RELATED_TO_FIGURE]->()
                DELETE r
            `, { goodsId: goods.id });
            
            // 创建新关系
            for (const figure of related_figures) {
                await session.run(`
                    MATCH (g:Goods {id: $goodsId})
                    MERGE (f:HistoricalFigure {name: $figureName, description: $figureDesc})
                    MERGE (g)-[:RELATED_TO_FIGURE]->(f)
                `, { 
                    goodsId: goods.id, 
                    figureName: figure.name,
                    figureDesc: figure.description || ''
                });
            }
        } else {
            // 如果没有历史人物数据，清空之前的数据
            await RelatedFigures.destroy({
                where: { goods_id: goods.id }
            });
            
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                OPTIONAL MATCH (g)-[r:RELATED_TO_FIGURE]->()
                DELETE r
            `, { goodsId: goods.id });
        }

        // 更新与历史事件的关系 - 同时更新MySQL和Neo4j
        if (related_events && related_events.length > 0) {
            // 先删除MySQL中的旧数据
            await RelatedEvents.destroy({
                where: { goods_id: goods.id }
            });
            
            // 添加新数据到MySQL
            for (const event of related_events) {
                await RelatedEvents.create({
                    goods_id: goods.id,
                    name: event.name,
                    date: event.date || '',
                    description: event.description || ''
                });
            }
            
            // 在Neo4j中创建关系
            // 先删除旧关系
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                OPTIONAL MATCH (g)-[r:RELATED_TO_EVENT]->()
                DELETE r
            `, { goodsId: goods.id });
            
            // 创建新关系
            for (const event of related_events) {
                await session.run(`
                    MATCH (g:Goods {id: $goodsId})
                    MERGE (e:HistoricalEvent {name: $eventName, date: $eventDate, description: $eventDesc})
                    MERGE (g)-[:RELATED_TO_EVENT]->(e)
                `, { 
                    goodsId: goods.id, 
                    eventName: event.name,
                    eventDate: event.date || '',
                    eventDesc: event.description || ''
                });
            }
        } else {
            // 如果没有历史事件数据，清空之前的数据
            await RelatedEvents.destroy({
                where: { goods_id: goods.id }
            });
            
            await session.run(`
                MATCH (g:Goods {id: $goodsId})
                OPTIONAL MATCH (g)-[r:RELATED_TO_EVENT]->()
                DELETE r
            `, { goodsId: goods.id });
        }

        // 创建工艺品之间的关系（相同地区或相似工艺）
        await session.run(`
            MATCH (g1:Goods {id: $goodsId})
            MATCH (g2:Goods)
            WHERE g2.id <> $goodsId
            OPTIONAL MATCH (g1)-[:BELONGS_TO_REGION]->(r:Region)<-[:BELONGS_TO_REGION]-(g2)
            OPTIONAL MATCH (g1)-[:BELONGS_TO_SCHOOL]->(s:CraftSchool)<-[:BELONGS_TO_SCHOOL]-(g2)
            WITH g1, g2, r, s
            WHERE r IS NOT NULL OR s IS NOT NULL
            MERGE (g1)-[rel:RELATED_TO]->(g2)
            SET rel.reasons = CASE
                WHEN r IS NOT NULL AND s IS NOT NULL THEN ["相同地区: " + r.name, "相似工艺: " + s.name]
                WHEN r IS NOT NULL THEN ["相同地区: " + r.name]
                ELSE ["相似工艺: " + s.name]
            END
        `, { goodsId: goods.id });

        res.send({
            code: 200,
            message: id ? '修改成功' : '新增成功',
            data: goods
        });
    } catch (e) {
        console.error('操作失败:', e);
        res.send({
            code: 500,
            message: e.message
        });
    }
});


//删除goods
router.delete('/:id', async (req, res) => {
    const session = req.neo4j.session();
    try {
        const {id} = req.params;
        const goods = await Goods.findByPk(id);
        if (!goods) {
            return res.send({
                code: 500,
                message: `未找到id为${id}的数据`
            });
        }
        
        // 先删除关联的历史人物和事件 (不需要手动删除，因为外键设置了级联删除)
        
        // 删除标签关联
        await goods.setTags([]);
        
        // 删除Neo4j中的节点和关系
        await session.run(`
            MATCH (g:Goods {id: $id})
            OPTIONAL MATCH (g)-[r]->()
            DELETE r, g
        `, { id });
        
        // 再删除商品本身
        await goods.destroy();
        
        res.send({
            code: 200,
            message: '删除成功'
        });
    } catch (e) {
        res.send({
            code: 500,
            message: e.message
        });
    }
});

module.exports = router;
